home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / souper15.zip / NNTPCL.C < prev    next >
C/C++ Source or Header  |  1996-05-18  |  5KB  |  252 lines

  1. /* $Id: nntpcl.c 1.4 1996/05/18 21:12:57 cthuang Exp $
  2.  *
  3.  * NNTP client routines
  4.  */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <netdb.h>
  12. #include "socket.h"
  13. #include "nntp.h"
  14. #include "nntpcl.h"
  15.  
  16. /* Open connection to NNTP server.
  17.  * Return socket handle or -1 on error.
  18.  */
  19. int
  20. nntpConnect (void)
  21. {
  22.     struct servent *sp;
  23.     char buf[BUFSIZ];
  24.     int response;
  25.     int socket;
  26.  
  27.     if (nntpServer == NULL) {
  28.     fprintf(stderr,
  29.         "Set the NNTPSERVER environment variable to the news host.\n");
  30.     exit(EXIT_FAILURE);
  31.     }
  32.  
  33.     if ((sp = getservbyname("nntp", "tcp")) == NULL) {
  34.     fprintf(stderr, "nntp/tcp: Unknown service.\n");
  35.     return -1;
  36.     }
  37.  
  38.     socket = Socket(nntpServer, ntohs(sp->s_port));
  39.     if (socket < 0) {
  40.     fprintf(stderr, "Cannot connect to news server %s\n", nntpServer);
  41.     return -1;
  42.     }
  43.  
  44.     if (SockGets(socket, buf, sizeof(buf)) == 0) {
  45.     response = atoi(buf);
  46.     switch (response) {
  47.     case OK_NOPOST:
  48.         printf("You cannot post articles to the news server %s\n",
  49.         nntpServer);
  50.         break;
  51.  
  52.     case OK_CANPOST:
  53.         break;
  54.  
  55.     case ERR_ACCESS:
  56.         printf("You do not have permission to use the news server %s\n",
  57.         nntpServer);
  58.         return -1;
  59.  
  60.     default:
  61.         printf("Unexpected response from news server %s\n", nntpServer);
  62.         puts(buf);
  63.         return -1;
  64.     }
  65.     }
  66.  
  67.     /* This is for INN */
  68.     SockPuts(socket, "mode reader");
  69.     SockGets(socket, buf, sizeof(buf));
  70.  
  71.     return socket;
  72. }
  73.  
  74. /* Close NNTP connection. */
  75.  
  76. void
  77. nntpClose (int socket)
  78. {
  79.     SockPuts(socket, "QUIT");
  80.     SockClose(socket);
  81. }
  82.  
  83. /* Select newsgroup to read from
  84.  * Return TRUE if successful.
  85.  */
  86. int
  87. nntpGroup (int socket, const char *ngname, ArticleNumber *pLo,
  88.     ArticleNumber *pHi)
  89. {
  90.     char buf[BUFSIZ];
  91.     int count;
  92.  
  93.     SockPrintf(socket, "GROUP %s\r\n", ngname);
  94.     if (SockGets(socket, buf, sizeof(buf)) != 0) {
  95.     return 0;
  96.     }
  97.  
  98.     if (buf[0] == CHAR_OK) {
  99.     sscanf(buf+4, "%d %d %d", &count, pLo, pHi);
  100.     } else {
  101.     fprintf(stderr, "%s: %s\n", buf, ngname);
  102.     }
  103.     return buf[0] == CHAR_OK;
  104. }
  105.  
  106. /* Request overview for the current newsgroup.
  107.  * Return TRUE if successful.
  108.  */
  109. int
  110. nntpXover (int socket, ArticleNumber lo, ArticleNumber hi)
  111. {
  112.     char buf[BUFSIZ];
  113.  
  114.     if (lo < hi)
  115.     SockPrintf(socket, "XOVER %ld-%ld\r\n", lo, hi);
  116.     else
  117.     SockPrintf(socket, "XOVER %ld\r\n", lo);
  118.  
  119.     if (SockGets(socket, buf, sizeof(buf)) != 0)
  120.     return 0;
  121.     if (buf[0] != CHAR_OK)
  122.     fprintf(stderr, "%s\n", buf);
  123.  
  124.     return buf[0] == CHAR_OK;
  125. }
  126.  
  127. /* Get next article in group.
  128.  * Return TRUE if successful.
  129.  */
  130. int
  131. nntpNext (int socket, ArticleNumber *pArtNum)
  132. {
  133.     char buf[BUFSIZ];
  134.  
  135.     SockPrintf(socket, "NEXT\r\n");
  136.     if (SockGets(socket, buf, sizeof(buf)) != 0) {
  137.     return 0;
  138.     }
  139.  
  140.     if (buf[0] == CHAR_OK) {
  141.     sscanf(buf+4, "%ld", pArtNum);
  142.     }
  143.     return buf[0] == CHAR_OK;
  144. }
  145.  
  146. /* Get article from server.
  147.  * Return TRUE if successful.
  148.  */
  149. int
  150. nntpArticle (int socket, const char *cmd, ArticleNumber artnum, FILE *outf)
  151. {
  152.     char buf[BUFSIZ];
  153.     char *bufp;
  154.  
  155.     SockPrintf(socket, "%s %ld\r\n", cmd, artnum);
  156.     if (SockGets(socket, buf, sizeof(buf)) < 0) {
  157.     return 0;
  158.     }
  159.  
  160.     if (buf[0] == CHAR_FATAL) {    /* Fatal error */
  161.     fprintf(stderr, "%s\n", buf);
  162.     exit(EXIT_FAILURE);
  163.     }
  164.  
  165.     if (buf[0] != CHAR_OK) {        /* and get it's reaction */
  166.     return 0;
  167.     }
  168.  
  169.     while (SockGets(socket, buf, sizeof(buf)) == 0) {
  170.     bufp = buf;
  171.     if (buf[0] == '.') {
  172.         ++bufp;
  173.         if (buf[1] == '\0')
  174.         break;
  175.     }
  176.  
  177.     fputs(bufp, outf);
  178.     fputc('\n', outf);
  179.     }
  180.  
  181.     return 1;
  182. }
  183.  
  184. /* Get date from server.
  185.  * Return TRUE if successful.
  186.  */
  187. int
  188. nntpDate (int socket, char *dest)
  189. {
  190.     char buf[BUFSIZ];
  191.  
  192.     SockPuts(socket, "DATE");
  193.     if (SockGets(socket, buf, sizeof(buf)) != 0) {
  194.     return 0;
  195.     }
  196.  
  197.     if (buf[0] == CHAR_INF) {
  198.     sscanf(buf+4, "%s", dest);
  199.     }
  200.     return buf[0] == CHAR_INF;
  201. }
  202.  
  203. /* Post article to NNTP server.
  204.  * Return TRUE if successful.
  205. */
  206. int
  207. nntpPost (int socket, FILE *inf, size_t bytes)
  208. {
  209.     char buf[BUFSIZ], *s;
  210.     size_t len, count;
  211.     long offset;
  212.  
  213.     SockPuts(socket, "POST");
  214.     if (SockGets(socket, buf, sizeof(buf)) < 0) {
  215.     return 0;
  216.     }
  217.     if (buf[0] != CHAR_CONT) {
  218.     if (atoi(buf) == ERR_NOPOST) {
  219.         fprintf(stderr, "You cannot post to this server.\n");
  220.     }
  221.     fprintf(stderr, "%s\n", buf);
  222.     return 0;
  223.     }
  224.  
  225.     offset = ftell(inf);
  226.     count = bytes;
  227.     while (fgets(buf, sizeof(buf), inf) && count > 0) {
  228.     count -= strlen(buf);
  229.     if ((s = strchr(buf, '\n')) != NULL)
  230.         *s = '\0';
  231.     if (buf[0] == '.')
  232.         SockWrite(socket, buf, 1);
  233.     SockPrintf(socket, "%s\r\n", buf);
  234.     }
  235.     fseek(inf, offset+bytes, SEEK_SET);
  236.  
  237.     SockPrintf(socket, ".\r\n");
  238.  
  239.     if (SockGets(socket, buf, sizeof(buf)) < 0) {
  240.     return 0;
  241.     }
  242.     if (buf[0] != CHAR_OK) {
  243.     if (atoi(buf) == ERR_POSTFAIL) {
  244.         fprintf(stderr, "Article not accepted by server; not posted.\n");
  245.     }
  246.     fprintf(stderr, "%s\n", buf);
  247.     return 0;
  248.     }
  249.  
  250.     return 1;
  251. }
  252.